import pyautogui
import pygetwindow as gw
import time
import cv2
import numpy as np
import pyperclip  # 用于读取剪贴板内容

# 确保操作延迟适中，避免过快导致失败
pyautogui.PAUSE = 0.3
pyautogui.FAILSAFE = True  # 鼠标移到左上角可终止程序

class WechatMessageCopier:
    def __init__(self):
        self.wechat_window = None
        # 对方消息气泡颜色范围（默认浅灰色，需根据实际调整）
        self.lower_color = np.array([0, 0, 200])    # HSV低阈值
        self.upper_color = np.array([180, 30, 255]) # HSV高阈值

    def get_wechat_window(self):
        """获取并激活微信窗口"""
        try:
            windows = gw.getWindowsWithTitle("微信")
            if windows:
                self.wechat_window = windows[0]
                if not self.wechat_window.isActive:
                    self.wechat_window.activate()
                time.sleep(1)  # 等待窗口激活
                return True
            print("未找到微信窗口")
            return False
        except Exception as e:
            print(f"获取窗口失败: {e}")
            return False

    def capture_chat_bottom(self):
        """截取聊天窗口底部区域（最新消息区域）"""
        if not self.wechat_window:
            return None
        
        # 聊天区域坐标（根据微信窗口调整）
        chat_x = self.wechat_window.left + 15
        chat_y = self.wechat_window.top + 60
        chat_width = self.wechat_window.width - 30
        chat_height = self.wechat_window.height - 180
        
        # 只截取底部20%区域（聚焦最新消息）
        bottom_height = int(chat_height * 0.2)
        bottom_y = chat_y + chat_height - bottom_height
        
        # 截取区域并转为OpenCV格式
        screenshot = pyautogui.screenshot(region=(chat_x, bottom_y, chat_width, bottom_height))
        return np.array(screenshot), (chat_x, bottom_y)  # 返回图像和区域起始坐标

    def find_last_opponent_bubble(self, image, start_coords):
        """找到底部区域内对方最后一个消息气泡"""
        hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
        mask = cv2.inRange(hsv, self.lower_color, self.upper_color)
        
        # 腐蚀膨胀去除噪声
        kernel = np.ones((5, 5), np.uint8)
        mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
        
        # 查找轮廓
        contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        if not contours:
            return None
        
        # 按轮廓底部y坐标排序（取最靠下的轮廓，即最后一条消息）
        contours.sort(key=lambda c: cv2.boundingRect(c)[1] + cv2.boundingRect(c)[3], reverse=True)
        last_contour = contours[0]
        
        # 获取气泡在屏幕上的绝对坐标
        x, y, w, h = cv2.boundingRect(last_contour)
        screen_x = start_coords[0] + x
        screen_y = start_coords[1] + y
        
        return (screen_x, screen_y, w, h)  # 气泡绝对坐标和尺寸

    def copy_message(self, bubble_rect):
        """模拟鼠标选中并复制消息"""
        x, y, w, h = bubble_rect
        
        # 移动到气泡内（偏左上方，避免点到头像）
        start_x = x + 20
        start_y = y + h // 2
        
        # 拖动选中文字（从左到右）
        pyautogui.moveTo(start_x, start_y)
        pyautogui.mouseDown()
        pyautogui.moveTo(x + w - 20, start_y, duration=0.5)  # 缓慢拖动确保选中
        pyautogui.mouseUp()
        
        # 复制选中内容（Ctrl+C）
        pyautogui.hotkey('ctrl', 'c')
        time.sleep(0.3)
        
        # 返回剪贴板内容
        return pyperclip.paste()

    def get_last_message(self):
        """获取对方最后一条消息主流程"""
        if not self.get_wechat_window():
            return None
        
        # 截取底部区域
        image, start_coords = self.capture_chat_bottom()
        if image is None:
            return None
        
        # 找到最后一个气泡
        bubble_rect = self.find_last_opponent_bubble(image, start_coords)
        if not bubble_rect:
            print("未找到对方消息")
            return None
        
        # 复制并返回消息
        message = self.copy_message(bubble_rect)
        return message.strip()

if __name__ == "__main__":
    copier = WechatMessageCopier()
    try:
        print("尝试获取对方最后一条消息（按Ctrl+C退出）...")
        while True:
            last_msg = copier.get_last_message()
            if last_msg:
                print(f"\n对方最后一条消息：{last_msg}")
            time.sleep(5)  # 每5秒检查一次
    except KeyboardInterrupt:
        print("\n程序已退出")
    